﻿using System;
using System.Linq;
using StockholmsStad.Data.Context;
using StockholmsStad.Data.ContractFactory;
using StockholmsStad.Data.Interfaces;
using StockholmsStad.Runtime.Serialization.DataContract;
using StockholmsStad.Utilities.Exceptions;
using StockholmsStad.Utilities.Enums;

namespace StockholmsStad.Data.DatabaseAgents
{
    internal class CoupleAgent : DBAgentBase, ICoupleAgent
    {
        #region Implementation of ICoupleAgent

        public Couple GetCouple(IDataContext context, int coupleId)
        {
            try
            {
                StockholmsStadDataContext dbCtx = context.GetInternalContext();
                var couple = dbCtx.Couples.Where(c => c.CoupleId == coupleId).SingleOrDefault();

                CoupleFactory factory = FactoryAgent.GetCoupleFactory();
                return factory.CreateContractObject(couple);
            }
            catch (Exception ex)
            {
                throw new StockholmStadSystemException(SystemErrorCode.DataAccessFailure, ex.InnerException ?? ex);
            }
        }

        /// <summary>
        /// Hämtar paret som hör till en viss användare
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i</param>
        /// <param name="userId">Nyckeln på användaren som hör till paret</param>
        /// <returns>Parets nyckel. </returns>
        public int GetCoupleId(IDataContext context, int userId)
        {
            try
            {
                StockholmsStadDataContext dbCtx = context.GetInternalContext();

                var ticket = dbCtx.Tickets.Where(t => t.UserId == userId).FirstOrDefault();

                if(ticket == null)
                    throw new StockholmStadSystemException(SystemErrorCode.UserHasNoTicket);

                return ticket.CoupleId;
            }
            catch (Exception ex)
            {
                throw new StockholmStadSystemException(SystemErrorCode.DataAccessFailure, ex.InnerException ?? ex);
            }
        }

        public int AddCouple(IDataContext context, Couple couple)
        {
            var factory = FactoryAgent.GetCoupleFactory();
            var entityCouple = factory.CreateEntityObject(couple);
            try
            {
                StockholmsStadDataContext dbCtx = context.GetInternalContext();
                return Insert(entityCouple, dbCtx);
            }
            catch (Exception ex)
            {
                throw new StockholmStadSystemException(SystemErrorCode.DataAccessFailure, ex.InnerException ?? ex);
            }
        }

        public void UpdateCouple(IDataContext context, int coupleId, Couple couple)
        {
            IPersonAgent personAgent = AgentFactory.GetPersonAgent();
            try
            {
                StockholmsStadDataContext dbCtx = context.GetInternalContext();
                var updateCouple = dbCtx.Couples.Where(c => c.CoupleId == coupleId).First();
                personAgent.UpdatePerson(context, updateCouple.PersonId1, couple.Person1);
                personAgent.UpdatePerson(context, updateCouple.PersonId2, couple.Person2);

                var oldContactPersonId = updateCouple.ContactPersonId;
                var contactPerson = couple.ContactPerson;

                if (contactPerson == null)
                {
                    updateCouple.ContactPerson = null;
                    dbCtx.SubmitChanges();
                }

                var personId = personAgent.UpdatePerson(context, oldContactPersonId, contactPerson);
                var person = (personId == null) ? null : dbCtx.Persons.Where(p => p.PersonId == personId.Value).Single();
                updateCouple.ContactPerson = person;
                dbCtx.SubmitChanges();
            }
            catch (Exception ex)
            {
                throw new StockholmStadSystemException(SystemErrorCode.DataAccessFailure, ex.InnerException ?? ex);
            }
        }

        public void RemindCoupleOfImpedimentDocMail(IDataContext context, string recipientEmail, Ticket ticket)
        {
            //try
            //{
            //    StockholmsStadDataContext dbCtx = context.GetInternalContext();
            //    var bookingAgent = AgentFactory.GetBookingAgent();
            //    var ministerAgent = AgentFactory.GetMinisterAgent();
            //    var ticketAgent = AgentFactory.GetTicketAgent();

            //    dbCtx.SendRemindCoupleOfImpedimentDocMail(recipientEmail, ticket.Ceremony.ImpedimentDocLatestDate);
            //    Booking booking = bookingAgent.GetBooking(context, ticket.TicketId);
            //    var minister = ministerAgent.GetMinisterByMinisterCode(context, booking.MinisterCode);

            //    if (minister.Email == null)
            //    {
            //        ticketAgent.InsertNotice(context, ticket.TicketId, string.Format(Resources.MinisterHasNoEmail, minister.FullName), "System");
            //    }
            //    else
            //    {
            //        dbCtx.NotifyMinisterServiceAboutRemindMail(minister.Email,
            //                                                  ticket.Ceremony.ImpedimentDocLatestDate,
            //                                                  ticket.Couple.Person1.FullName,
            //                                                  ticket.Couple.Person2.FullName);
            //    }
            //}
            try
            {
                StockholmsStadDataContext dbCtx = context.GetInternalContext();
                dbCtx.SendRemindCoupleOfImpedimentDocMail(recipientEmail, ticket.Ceremony.ImpedimentDocLatestDate);
            }
            catch (Exception ex)
            {
                throw new StockholmStadSystemException(SystemErrorCode.DataAccessFailure, ex.InnerException ?? ex);
            }
        }

        

        #endregion
    }
}